package com.rxt.thermopro.ui.fragment

import android.content.DialogInterface
import android.graphics.Rect
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.app.common.base.BaseFragment
import com.app.common.ex.toast
import com.rxt.ble.BleManager
import com.rxt.ble.data.BleDevice
import com.rxt.thermopro.R
import com.rxt.thermopro.adapter.DeviceListAdapter
import com.rxt.thermopro.adapter.DeviceListAdapter.Companion.VIEW_TYPE_BBQ
import com.rxt.thermopro.adapter.DeviceListAdapter.Companion.VIEW_TYPE_GRILL
import com.rxt.thermopro.adapter.DeviceListAdapter.Companion.VIEW_TYPE_TP359
import com.rxt.thermopro.adapter.DeviceListAdapter.Companion.VIEW_TYPE_TP960
import com.rxt.thermopro.adapter.DeviceListAdapter.Companion.VIEW_TYPE_UNKNOWN
import com.rxt.thermopro.app.AppContext
import com.rxt.thermopro.app.LocalDataDao
import com.rxt.thermopro.bean.DeviceBean
import com.rxt.thermopro.bean.ProbeBean
import com.rxt.thermopro.bean.ProfileBean
import com.rxt.thermopro.viewmodel.BleMessageViewModel
import com.rxt.thermopro.viewmodel.DeviceListViewModel
import com.rxt.thermopro.viewmodel.DeviceStatusViewModel
import com.rxt.thermopro.viewmodel.EventViewModel
import kotlinx.android.synthetic.main.fragment_device_list.*
import kotlinx.android.synthetic.main.fragment_device_list.mainMenuButton

class DeviceListFragment : BaseFragment<DeviceListViewModel>() {

    override fun layoutId(): Int {
        return R.layout.fragment_device_list
    }

    companion object {
        private const val ARG_SECTION_NUMBER = "number"

        fun newInstance(sectionNumber: Int): DeviceListFragment {
            return DeviceListFragment().apply {
                arguments = Bundle().apply {
                    putInt(ARG_SECTION_NUMBER, sectionNumber)
                }
            }
        }
    }

    private var listDialog: BluetoothListDialog? = null
    private lateinit var adapter: DeviceListAdapter
    private val deviceList = mutableListOf<DeviceBean>()
    private lateinit var mEventViewModel: EventViewModel
    private lateinit var mBleViewModel: BleMessageViewModel
    private lateinit var mDeviceStatusViewModel: DeviceStatusViewModel


    private val refreshTempDataCache = hashMapOf<String, MutableList<ProbeBean>>()

    override fun initView(savedInstanceState: Bundle?) {
        mDeviceStatusViewModel =
            ViewModelProvider(requireActivity()).get(DeviceStatusViewModel::class.java)
        mEventViewModel = ViewModelProvider(requireActivity()).get(EventViewModel::class.java)
        mBleViewModel =
            ViewModelProvider(requireActivity()).get(BleMessageViewModel::class.java)

        adapter = DeviceListAdapter(deviceList)
        adapter.setDevicePresenter(DevicePresenter())
        recyclerDevice.layoutManager = LinearLayoutManager(context)
        recyclerDevice.adapter = adapter
        recyclerDevice.addItemDecoration(object : RecyclerView.ItemDecoration() {
            override fun getItemOffsets(
                outRect: Rect,
                view: View,
                parent: RecyclerView,
                state: RecyclerView.State
            ) {
//                outRect.right = resources.getDimensionPixelSize(R.dimen.item_margin)
//                outRect.left = resources.getDimensionPixelSize(R.dimen.item_margin)
                if (parent.getChildLayoutPosition(view) == 0) {
                    outRect.top = 0
                } else {
                    outRect.top = resources.getDimensionPixelSize(R.dimen.item_top_margin)
                }
                //最后一行下边距
                if (parent.getChildLayoutPosition(view) == parent.childCount - 1) {
                    outRect.bottom = resources.getDimensionPixelSize(R.dimen.item_margin)
                } else {
                    outRect.bottom = 0
                }
            }
        })

        mBleViewModel.notifyMsgData.observeInFragment(this, Observer { item ->
            val it = item.values.last()
            println("======>  deviceListFragment notifyMsgData=$it")
            adapter.update(it)
            if (adapter.getDeviceType(it.last().address) != VIEW_TYPE_TP359) {
                for (i in 0 until it.size) {
                    val profile = when (i) {
                        0 -> {
                            LocalDataDao.INSTANCE.getProfile1(it[i].address)
                        }
                        1 -> {
                            LocalDataDao.INSTANCE.getProfile2(it[i].address)
                        }
                        else -> {
                            ProfileBean(
                                "MEAT",
                                "", mutableListOf(), singleTemp = false
                            )
                        }
                    }
//                    if (profile.highTemperatureNum.isNotEmpty()) {
//                        if (it[i].temperatureNUm.isNotEmpty() && it[i].temperatureNUm.toInt() >= (profile.highTemperatureNum.toIntOrNull()
//                                ?: 0)
//                        ) {
//                            mDeviceStatusViewModel.resetBlockWorking(0, it[i].address)
//                        }
//                    }
                }
            }
        })

        mBleViewModel.notifyRefreshTempData.observeForever(Observer {
            val address = it.last().address
            if (refreshTempDataCache.containsKey(address)) {
                refreshTempDataCache.remove(address)
            }
            refreshTempDataCache[address] = it
        })

        mBleViewModel.notifyInfoData.observeInFragment(this, Observer {
            println("======>DeviceListFragment setBatteryLevel  ${it.electricity}")
            adapter.updateBattery(
                it.address,
                it.electricity.toInt()
            )
        })

        mBleViewModel.connectSuccess.observeInFragment(this, Observer {
            if (adapter.getDeviceType(it.keys.last()) == VIEW_TYPE_TP960) {
//                mViewModel.setProfile(profileArray[0], 0, mData.address)
                //历史温度
                mViewModel.getHistoryTemp(it.keys.last(), 0)
            }
        })

//        mViewModel.getHistoryTempByCache.observeInFragment(this, Observer {
//            mBleViewModel.getTempHistoryByCache(it.keys.last(), "TP960")
//        })

        //TP960预测时间
//        mBleViewModel.notifyHistoryTempTP960Data.observeInFragment(this, Observer { item ->
//            if (item.isNotEmpty() && item[0]?.isNotEmpty() == true) {
//                val bean = adapter.getItemByAddress(item[0]?.first()?.address ?: "")
//                item[0]?.let {
//                    if ((bean.targetTemp1.toDoubleOrNull() ?: 0.0) != 0.0) {
//                        mDeviceStatusViewModel.computeNeedTime(
//                            it.first().address,
//                            0, bean.targetTemp1.toDoubleOrNull() ?: 0.0, it
//                        )
//                    }
//                }
//            }
//        })

        mDeviceStatusViewModel.needTimeClock1.observeInFragment(this, Observer {
            adapter.updateClockTime(it, 0)
        })

        //预测时间（修改）
        mBleViewModel.probeTempComputeTime.observeForever(Observer {
            mViewModel.compute2TempTime.postValue(it.second)
            //剩余时间倒计时
            val address = it.second.keys.last().split("_")[0]
            val clockIndex = it.second.keys.last().split("_")[1].toIntOrNull() ?: -1
            if (it.second.values.last().split(":").size > 2) {
                println("123->  mDeviceStatusViewModel  startTimeClock ")
                mDeviceStatusViewModel.startTimeClock(
                    address,
                    clockIndex,
                    it.second.values.last()
                )
            } else {
                if (mDeviceStatusViewModel.isBlockTimeWorking(clockIndex, address)) {
                    mDeviceStatusViewModel.resetBlockTimeWorking(clockIndex, address)
                }
            }
        })

        mViewModel.compute2TempTime.observeInFragment(this, Observer {
            if (it.isNotEmpty()) {
                adapter.updateNeedTime(it)
            }
        })

        mBleViewModel.disconnectData.observeInFragment(this, Observer {
            adapter.refreshDeviceStatus()
            if (adapter.getDeviceType(it.first) == VIEW_TYPE_TP960) {
                //停止倒计时
                mDeviceStatusViewModel.resetBlockTimeWorking(0, it.first)
            }
        })

        mViewModel.deviceListData.observe(this, Observer {
            adapter.addAll(it)
            if (it.isNotEmpty()) {
                showRecycler(true)
//                mBleViewModel.connectBleList(it)
            }
            //开始连接
            if (requireActivity() is AppCompatActivity) {
                println("=====>  AppContext.get().startCheckConnectWorking")
                AppContext.get()
                    .startCheckConnectWorking(requireActivity() as AppCompatActivity)
            }
        })

        mBleViewModel.signalLevel.observeInFragment(this, Observer {
            println("=====>  setSignal deviceListFragment $it")
            if (it.isNotEmpty() && it.values.isNotEmpty() && it.values.last().isNotEmpty()) {
                adapter.updateSignal(it.values.last().keys.last(), it.values.last().values.last())
            }
        })

        mBleViewModel.notifyTP960ProbeStatusForever.observeForever(Observer {
            if (it.isNotEmpty()) {
                it[it.keys.last()]?.let { item ->
                    val newIt = hashMapOf<String, Pair<Int, String>>().apply {
                        this[it.keys.last()] =
                            item.first to (item.second.toString() + "_0")
                    }
                    mViewModel.notifyTP960ProbeStatus.postValue(newIt)
                }
            }
        })

        mViewModel.notifyTP960ProbeStatus.observeInFragment(this, Observer {
            adapter.updateTP960ProbeStatus(
                it.keys.last(),
                it.values.last().first,
                it.values.last().second.split("_")[0].toIntOrNull() ?: 0
            )
        })

        mBleViewModel.loadCacheData.observeInFragment(this, Observer {
            if (mBleViewModel.notifyInfoDataCache.isNotEmpty()) {
                adapter.updateBattery(
                    mBleViewModel.notifyInfoDataCache.last().first,
                    mBleViewModel.notifyInfoDataCache.last().second.electricity.toInt()
                )
            }
            if (mBleViewModel.signalLevelCache.isNotEmpty()) {
                adapter.updateSignal(
                    mBleViewModel.signalLevelCache.keys.last(),
                    mBleViewModel.signalLevelCache.values.last()
                )
            }
        })

        mEventViewModel.refreshTempUnit.observeInFragment(this, Observer {
            adapter.refreshTempUnit()
        })

        mDeviceStatusViewModel.profileData1.observeInFragment(this, Observer {
            adapter.updateTP960TargetTemp(it, 1)
        })

        mDeviceStatusViewModel.profileData2.observeInFragment(this, Observer {
            adapter.updateTP960TargetTemp(it, 2)
        })

        mDeviceStatusViewModel.removeDevice.observeInFragment(this, Observer {
            if (it.values.isNotEmpty()) {
                adapter.remove(it.values.last())
                if (adapter.itemCount <= 0) {
                    showRecycler(false)
                }
                mViewModel.removeDevice(it.values.last())
                mBleViewModel.removeDevice(it.values.last())
            }
        })

        initListener()

        mViewModel.initDeviceData()

        //后台重连
        if (!AppContext.get().isServiceConnected()) {
            AppContext.get().connectService()
            mViewModel.postDelay({
                AppContext.get().startCheckConnectWorking(requireActivity())
            }, 3000)
        }
    }

    override fun onResume() {
        super.onResume()
        if (refreshTempDataCache.isNotEmpty()) {
            refreshTempDataCache.keys.forEach {
                mBleViewModel.notifyMsgData.value =
                    hashMapOf<Long, MutableList<ProbeBean>>().apply {
                        this[System.currentTimeMillis()] = mutableListOf<ProbeBean>().apply {
                            this.addAll(refreshTempDataCache[it] ?: emptyList())
                        }
                    }
            }
        }
        if (!BleManager.getInstance().isBlueEnable) {
            BleManager.getInstance().enableBluetooth()
        }
    }

    private fun initListener() {
        mainMenuButton.setOnClickListener {
            println("123-> add SettingFragment")
            parentFragmentManager.beginTransaction()
                .setCustomAnimations(
                    R.anim.translate_into, R.anim.translate_out,
                    R.anim.translate_into_pop, R.anim.translate_out_exit
                )
                .add(
                    R.id.mainContent,
                    SettingFragment.newInstance()
                )
                .addToBackStack("main")
                .commit()
        }

        mainAdd.setOnClickListener {
            searchDevice()
        }

        viewAddDevice.setOnClickListener {
            searchDevice()
        }
    }

    private fun searchDevice() {
        listDialog = BluetoothListDialog()
        listDialog?.showDialog(childFragmentManager)
        listDialog?.setOnDialogBluetoothListener(object :
            BluetoothListDialog.OnDialogBluetoothListener {
            override fun onItemClick(name: String?, address: String, bleDevice: BleDevice?) {
                val deviceType = when {
                    name?.contains("bbq", true) == true ||
                            bleDevice?.name?.contains("tp930", true) == true -> {
                        VIEW_TYPE_BBQ
                    }
                    name?.contains("grill", true) == true ||
                            bleDevice?.name?.contains("tp920", true) == true -> {
                        VIEW_TYPE_GRILL
                    }
                    name?.contains("tp359", true) == true -> {
                        VIEW_TYPE_TP359
                    }
                    name?.contains("tp960r", true) == true -> {
                        VIEW_TYPE_TP960
                    }
                    else -> {
                        VIEW_TYPE_UNKNOWN
                    }
                }
                if (deviceType == VIEW_TYPE_UNKNOWN) {
                    toast(R.string.text_unkonwn_device)
                    return
                }
                val itemBean = DeviceBean(
                    name, address, "",
                    "", bleDevice, "", deviceType = deviceType
                )
                if (deviceType == VIEW_TYPE_TP960) {
                    itemBean.targetTemp1 =
                        LocalDataDao.INSTANCE.getProfile1(address).highTemperatureNum
                    itemBean.targetTemp2 =
                        LocalDataDao.INSTANCE.getProfile2(address).highTemperatureNum
                }
                val filterList = adapter.list.filter { it.deviceType != VIEW_TYPE_TP359 }
                if (filterList.size > 2) {
                    toast(R.string.text_device_too_much)
                } else {
                    if (!adapter.hasBlueDevice(itemBean.address)) {
                        adapter.add(itemBean)
                        mViewModel.saveDevice(itemBean)
                        showRecycler(true)
                    }
                    mBleViewModel.connectBluetooth(
                        ProbeBean(
                            name = itemBean.name ?: "",
                            address = itemBean.address
                        )
                    )
                }
            }

            override fun onCancel() {

            }

        })
    }

    private fun showRecycler(isShow: Boolean) {
        if (isShow) {
            recyclerDevice.visibility = View.VISIBLE
            noDevice.visibility = View.GONE
            viewAddDevice.setText(R.string.text_add_device)
        } else {
            recyclerDevice.visibility = View.GONE
            noDevice.visibility = View.VISIBLE
            viewAddDevice.setText(R.string.text_add_device)
        }
    }

    inner class DevicePresenter() {
        fun onItemClick(view: View, position: Int) {
            val toFragment = when {
                adapter.list[position].name?.contains("bbq", true) == true -> {
                    BBQFragment.newInstance(
                        adapter.list[position].name ?: "",
                        adapter.list[position].address
                    )
                }
                adapter.list[position].name?.contains("grill", true) == true -> {
                    BBQFragment.newInstance(
                        adapter.list[position].name ?: "",
                        adapter.list[position].address
                    )
                }
                adapter.list[position].name?.contains("tp960", true) == true -> {
                    TP960Fragment.newInstance(
                        adapter.list[position].name ?: "",
                        adapter.list[position].address,
                        adapter.list[position].probeStatus1 == 1
                    )
                }
                else -> {
                    DataChartsFragment.newInstance(
                        adapter.list[position].name ?: "",
                        adapter.list[position].address
                    )
                }
            }
            parentFragmentManager.beginTransaction()
                .setCustomAnimations(
                    R.anim.translate_into, R.anim.translate_out,
                    R.anim.translate_into_pop, R.anim.translate_out_exit
                )
                .add(
                    R.id.mainContent,
                    toFragment
                )
                .addToBackStack("main")
                .commit()
//            mViewModel.writeMsgToBluetooth(adapter.list[position].bleDevice)
        }

        fun deleteDevice(item: DeviceBean, position: Int) {
            val dialog = AlertDialog.Builder(requireContext())
                .setMessage(R.string.text_sure_delete_device)
                .setNegativeButton(
                    R.string.text_Cancel
                ) { _, _ ->

                }
                .setPositiveButton(R.string.text_yes) { _, _ ->
                    adapter.remove(position)
                    if (adapter.itemCount <= 0) {
                        showRecycler(false)
                    }
                    mViewModel.removeDevice(item)
                    mBleViewModel.removeDevice(item)
                }
                .show()
            dialog.getButton(DialogInterface.BUTTON_POSITIVE)
                .setTextColor(resources.getColor(R.color.gray_text))
            dialog.getButton(DialogInterface.BUTTON_NEGATIVE)
                .setTextColor(resources.getColor(R.color.gray_text))
        }
    }

}